<?php

declare (strict_types = 1);

namespace app\common\service\system;

use app\common\model\BaseModel;
use app\common\service\BaseService;
use app\common\exception\AdminException;
use app\common\repository\system\SysConfigRepository;
use app\common\service\system\SysConfigGroupService;
use think\Config;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;
use think\facade\Log;

class SysConfigService extends BaseService
{
    // 缓存标签
    const CACHE_TAG = 'system_config_tag';

    public function __construct(SysConfigRepository $repository)
    {
        $this->repository = $repository;
    }

    /**
     * 获取配置列表
     *
     * @param array $where
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function getList(array $where = []): array
    {
        [$page, $pageSize] = $this->getPaginationParams();
        unset($where['page'], $where['page_size']);
        return $this->repository->paginate($where, ['id' => 'desc'], $page, $pageSize);
    }

    /**
     * 后台获取分组配置项
     *
     * @param string $mark
     * @return false|mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getGroupConfig(string $mark): mixed
    {
        $groupService = app()->make(SysConfigGroupService::class);
        return $groupService->getGroupConfigs($mark);
    }

    /**
     * 统一获取配置方法
     * @param string $identifier 格式 group_mark 或 group_mark.key
     * @return mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getConfig(string $identifier): mixed
    {
        // 解析标识符类型
        if (str_contains($identifier, '.')) {
            return $this->getItemConfig($identifier); // 格式：group_mark.key
        }
        $groupService = app()->make(SysConfigGroupService::class);
        $groupConfig = $groupService->getGroupConfigs($identifier); // 格式：group_mark
        return array_column($groupConfig['configs'], 'value', 'key');
    }

    /**
     * 获取单项配置
     *
     * @param string $key
     * @return mixed
     */
    public function getItemConfig(string $key): mixed
    {
        [$groupMark, $configKey] = explode('.', $key, 2);

        $cacheKey = 'system_config:' . $key;

        $config = Cache::get($cacheKey);

        if(empty($config)) {
            $sysGroupService = app()->make(SysConfigGroupService::class);
            // 用mark查询id
            $groupId = $sysGroupService->getValue('id', ['mark' => $groupMark]);
            $config = $this->repository->getValue('value', ['key' => $configKey, 'group_id' => $groupId]);
            Cache::tag(self::CACHE_TAG)->set($cacheKey, $config, 3600);
        }

        return $config;
    }

    /**
     * 修改配置值
     *
     * @param $data
     * @return true
     */
    public function updateConfigValue($data): true
    {
        try {
            // 执行事务操作
            $this->transaction(function () use ($data) {
                foreach ($data as $key => $value) {
                    $this->repository->update(['value' => $value], ['key' => $key]);
                }
            });

            // 事务成功提交后清理缓存
            Cache::tag(self::CACHE_TAG)->clear();
            return true;
        } catch (\Throwable $e) {
            throw new AdminException('配置更新失败: '.$e->getMessage(), $e->getCode(), $e);
        }
    }

    /**
     * 获取配置分类详情信息
     *
     * @param $id
     * @return BaseModel|null
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getInfo($id): ?BaseModel
    {
        return $this->repository->getOne($id);
    }

    /**
     * 创建配置分类信息
     *
     * @param array $params
     * @return BaseModel|array
     * @throws \Exception
     */
    public function create(array $params): BaseModel|array
    {
        $data = [
            'title' => $params['title'],
            'key' => $params['key'],
            'value' => $params['value'],
            'type' => $params['type'],
            'options' => $params['options'],
            'sort' => $params['sort'],
            'remark' => $params['remark'],
            'status' => $params['status'],
            'group_id' => $params['group_id'],
        ];
        $result = $this->repository->save($data);
        if($result) {
            Cache::tag(self::CACHE_TAG)->clear();
        }
        return $result;
    }

    /**
     * 更新配置分类信息
     *
     * @param array $params
     * @param $id
     * @return bool|int
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function update(array $params, $id): bool|int
    {
        if(empty($id)) {
            throw new AdminException('ID 不能为空');
        }

        $data = [
            'title' => $params['title'],
            'key' => $params['key'],
            'value' => $params['value'],
            'type' => $params['type'],
            'options' => $params['options'],
            'sort' => $params['sort'],
            'remark' => $params['remark'],
            'status' => $params['status'],
            'group_id' => $params['group_id'],
        ];

        $result = $this->repository->update($data, $id);
        if($result) {
            Cache::tag(self::CACHE_TAG)->clear();
        }
        return $result;
    }

    /**
     * 删除配置分类信息
     *
     * @param $id
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function delete($id): bool
    {
        Cache::tag(self::CACHE_TAG)->clear();
        return $this->repository->delete($id);
    }
}